﻿using System;
using System.Linq;
using Microsoft.TeamFoundation.VersionControl.Common;
using NotifyPilot.Models;

namespace NotifyPilot.WCF.Helpers
{
    public class TFSContentObjectFactory
    {
        public static TFSContentObject CreateTFSContentObject(String xmlEvent, String tfsRootUrl)
        {
            if (xmlEvent.StartsWith("<WorkItemChangedEvent"))
            {
                var workItemChangedEvent = Helpers.DeserializeChangeObject<WorkItemChangedEvent>(xmlEvent);
                return new TFSContentObject(workItemChangedEvent, tfsRootUrl);

            }
            if (xmlEvent.StartsWith("<CheckinEvent"))
            {
                var checkinEvent = Helpers.DeserializeChangeObject<CheckinEvent>(xmlEvent);
                return new TFSContentObject(checkinEvent, tfsRootUrl);
            }
            return null;
        }

        public static EventType GetEventClass(String xmlEvent)
        {
            if (xmlEvent.StartsWith("<WorkItemChangedEvent"))
            {
                return EventType.WorkItemChangedEvent;
            }
            if (xmlEvent.StartsWith("<CheckinEvent"))
            {
                return EventType.CheckinEvent;
            }
            if (xmlEvent.StartsWith("<todefine")) // todo : find the begin of build events
            {
                return EventType.Builds;
            }

            return EventType.Unknow;
        }
    }

    // todo : implement mapping for shelvechanged &  build events
    public class TFSContentObject
    {
        public int ID { get; set; }
        public String Name { get; set; }
        public String Descriptions { get; set; }
        public String More { get; set; }
        public String Url { get; set; }
        public String ProjectName { get; set; }
        public String Iteration { get; set; }
        public String WorkItemType { get; set; }
        public String HourStatus { get; set; }
        public Boolean ChangeState { get; set; }
        public String ChangedBy { get; set; }
        public DateTime ChangedDate { get; set; }

        public TFSContentObject(CheckinEvent checkinEvent, String tfsRoorUrl)
        {
            this.Name = String.IsNullOrWhiteSpace(checkinEvent.Comment)
                ? checkinEvent.ContentTitle
                : checkinEvent.Comment;
            this.More = String.Empty;
            this.Url = tfsRoorUrl + "_versionControl/changeset?id=" + checkinEvent.Number;
            ProjectName = checkinEvent.TeamProject;

            String artifacts =
                (from ClientArtifact t in checkinEvent.Artifacts where !String.IsNullOrEmpty(t.Item) select t).Aggregate
                    ("", (current, t) => current + (t.Item + ", "));

            if (artifacts.Length > 0)
            {
                this.More += artifacts.Substring(0, artifacts.Length - 2);
            }
        }

        public TFSContentObject(WorkItemChangedEvent wik, String tfsRoorUrl)
        {
            this.ID = wik.GetPropertyIntValue("System.Id");
            this.Name = wik.WorkItemTitle;
            this.Url = String.Format("{0}{1}/_workItems#_a=edit&id={2}", tfsRoorUrl, wik.PortfolioProject,
                      this.ID);
            this.Descriptions = String.Empty;
            this.ProjectName = wik.PortfolioProject;
            this.Iteration = wik.GetPropertyStringValue("System.IterationPath");
            this.WorkItemType = wik.GetPropertyStringValue("System.WorkItemType");
            this.ChangedDate = wik.GetPropertyDateTimeValue("System.ChangedDate") ??
                        wik.GetPropertyDateTimeValue("System.CreatedDate") ??
                        DateTime.UtcNow;
            this.ChangedBy = wik.GetPropertyStringValue("System.ChangedBy") ??
                wik.GetPropertyStringValue("System.CreatedBy") ??
                "unknow";

            StringField state =
                wik.CoreFields.StringFields.FirstOrDefault(p => p.ReferenceName == "System.State" &&
                                                                p.NewValue != p.OldValue);
            if (state != null) // Check if state changed
            {
                this.ChangeState = true;
                this.Descriptions = String.Format("  State have been changed from {0} to {1}", state.OldValue,
                    state.NewValue);
                String reason = wik.GetPropertyStringValue("System.Reason");
                if (!String.IsNullOrEmpty(reason)) this.Descriptions += String.Format(" (Reason : {0})", reason);
            }

            StringField assigned =
                wik.CoreFields.StringFields.FirstOrDefault(p => p.ReferenceName == "System.AssignedTo" &&
                                                                (p.NewValue ?? "") != (p.OldValue ?? ""));
            if (assigned != null) // check if assigned to changed
                this.Descriptions += !String.IsNullOrEmpty(assigned.NewValue)
                    ? String.Format("  Assigned to {0}", assigned.NewValue)
                    : "Unassigned";
        }
    }
}
